#include "DataStorageAddressableLed.h"
#include <EEPROM.h>
#include "log.h"

AddressableLedData::AddressableLedData(Mail<>& mb):_mb(mb)
{

}

bool AddressableLedData::load()
{
    if(this->read_data_storage_eof() != DATA_STORAGE_EOF){
        return false;
    }
    for(uint32_t i=0;i<sizeof(AddressableLedData::module_reg().module_header_reg.data);i++){
         module_header_reg().data[i] = EEPROM.read(i);
    }
    //载入模组通用信息
    for(uint32_t i=sizeof(AddressableLedData::module_reg().module_header_reg.data);
                 i<(sizeof(AddressableLedData::module_reg().module_header_reg.data)+sizeof(AddressableLedData::module_reg().module_general_reg.data));
                 i++){
        module_reg().module_general_reg.data[i-sizeof(AddressableLedData::module_reg().module_header_reg.data)] = EEPROM.read(i);
    }
    return true;

}
int AddressableLedData::read_data_storage_eof()
{
    int eof_address= sizeof(AddressableLedData::module_reg().module_header_reg.data)+sizeof(AddressableLedData::module_reg().module_general_reg.data);
    _data_storage_eof._AA = EEPROM.read(eof_address);
    _data_storage_eof._55 = EEPROM.read(eof_address+1);
    return _data_storage_eof.value;
}

void AddressableLedData::make_default()
{
     //生成头部信息
    module_header_reg().module_number.value      = 0x0003;
    module_header_reg().hardware_version         = 0x01;
    module_header_reg().software_version         = 0x01;
    module_header_reg().module_type              = 1;
    module_header_reg().protocol_part_1.value    = 0x87;
    module_header_reg().protocol_part_2.value    = 0x01;
    strcpy((char*)module_header_reg().module_name,"WF1-Addressable_LED_3");
    
    //写入头部信息到EEPROM
    for(uint8_t i=0;i<sizeof(AddressableLedData::module_reg().module_header_reg.data);i++){
        EEPROM.write(i, module_header_reg().data[i]); 
    }

    module_general_reg_t& module_general_reg = AddressableLedData::module_reg().module_general_reg;
    //生成寄存器默认配置
    module_general_reg.module_mux_enable_reg.value = 0;
    module_general_reg.module_mux0_channel_select_reg.value = 0x01;
    module_general_reg.module_mux1_channel_select_reg.value = 0x01;
    module_general_reg.module_mux2_channel_select_reg.value = 0x01;

    //写入默认配置到EEPROM
    for(uint32_t i=sizeof(AddressableLedData::module_reg().module_header_reg.data);
            i<(sizeof(AddressableLedData::module_reg().module_header_reg.data)+sizeof(AddressableLedData::module_reg().module_general_reg.data));
            i++)
    {
        EEPROM.write(i, module_general_reg.data[i-sizeof(AddressableLedData::module_reg().module_header_reg.data)]);
    }
    //写入0x55AA激活配置

    EEPROM.write(sizeof(AddressableLedData::module_reg().module_header_reg.data)+sizeof(AddressableLedData::module_reg().module_general_reg.data),0xAA);
    EEPROM.write(sizeof(AddressableLedData::module_reg().module_header_reg.data)+sizeof(AddressableLedData::module_reg().module_general_reg.data)+1,0x55);
}

void AddressableLedData::check_update()
{
    bool _update = false;

    for(uint32_t i=0;i<sizeof(AddressableLedData::module_reg().module_header_reg.data);i++){
        if(!_mb.empty()){
            return;
        }
        if(EEPROM.read(i) !=  module_header_reg().data[i]){
            _update = true;
            break;
        }
    }

    if(_update){
        for(uint32_t i=0;i<sizeof(AddressableLedData::module_reg().module_header_reg.data);i++){
            if(!_mb.empty()){
                return;
            }
            EEPROM.write(i, module_header_reg().data[i]);
        }
        //log::debug("update eeprom header:%s\r\n",_update?"Y":"N");
    }

    _update = false;
    
    module_general_reg_t& module_general_reg = AddressableLedData::module_reg().module_general_reg;
    for(uint32_t _check_index=sizeof(AddressableLedData::module_reg().module_header_reg.data);
        _check_index<(sizeof(AddressableLedData::module_reg().module_header_reg.data)+sizeof(AddressableLedData::module_reg().module_general_reg.data));
        _check_index++){
        if(!_mb.empty()){
            return;
        }
        if(EEPROM.read(_check_index) !=  module_general_reg.data[_check_index-sizeof(AddressableLedData::module_reg().module_header_reg.data)]){
            _update = true;
            break;
        }
    }

    
    if(_update){
    //写入默认配置到EEPROM
        for(uint8_t i=sizeof(AddressableLedData::module_reg().module_header_reg.data);
                i<(sizeof(AddressableLedData::module_reg().module_header_reg.data)+sizeof(AddressableLedData::module_reg().module_general_reg.data));
                i++){
            if(!_mb.empty()){
                return;
            }
            EEPROM.write(i,module_general_reg.data[i-sizeof(AddressableLedData::module_reg().module_header_reg.data)]);
        }
        //log::debug("update eeprom reg:%s\r\n",_update?"Y":"N");
    }

}


data_storage_reg_read_t& AddressableLedData::get_reg_data(uint8_t reg_address)
{
    switch (reg_address)
    {
        case 0x00:
        case 0x01:
        {
            _reg_read.data    =  module_header_reg().module_number.data;
            _reg_read.size    = sizeof( module_header_reg().module_number.data);
        }
        break;
        case 0x02:
        {
            _reg_read.data    =  module_header_reg().hardware_version_data;
            _reg_read.size    = sizeof( module_header_reg().hardware_version_data);
        }
        break;
        case 0x03:
        {
            _reg_read.data    =  module_header_reg().software_version_data;
            _reg_read.size    = sizeof( module_header_reg().software_version_data);
        }
        break;
        case 0x04:
        {
            _reg_read.data    =  module_header_reg().module_type_data;
            _reg_read.size    = sizeof( module_header_reg().module_type_data);
        }
        break;
        case 0x05:
        case 0x06:
        {
            _reg_read.data    =  module_header_reg().protocol_data;
            _reg_read.size    = sizeof( module_header_reg().protocol_data);
        }
        break;
        case 0x07:
        {
            _reg_read.data    =  AddressableLedData::module_reg().module_header_reg.module_name;
            _reg_read.size    = 21;
        }
        break;
    case 0x42:
        break;
    case 0x43:
        break;
    case 0x44:
        break;
    case 0x45:
        break;
    case 0x46:
        break;
    case 0x47:
        break;
    case 0x48:
        {
            module_general_reg_t& general_reg = AddressableLedData::module_reg().module_general_reg;

            _reg_read.data     =  general_reg.module_mux_enable_reg.data;
            _reg_read.size     =   sizeof(general_reg.module_mux_enable_reg.data);
        }
        break;
    case 0x49:break;
    case 0x4A:
    { 
        module_general_reg_t& general_reg = AddressableLedData::module_reg().module_general_reg;
        _reg_read.data     =  general_reg.module_mux0_channel_select_reg.data;
        _reg_read.size     =   sizeof(general_reg.module_mux0_channel_select_reg.data);
    }
    break;
    case 0x4B:// 
    {
       module_general_reg_t& general_reg = AddressableLedData::module_reg().module_general_reg;
        _reg_read.data     =  general_reg.module_mux1_channel_select_reg.data;
        _reg_read.size     =   sizeof(general_reg.module_mux1_channel_select_reg.data);   
    }
    break;
    case 0x4C://
    {
        module_general_reg_t& general_reg = AddressableLedData::module_reg().module_general_reg;
        _reg_read.data     =  general_reg.module_mux2_channel_select_reg.data;
        _reg_read.size     =   sizeof(general_reg.module_mux2_channel_select_reg.data);
    }
    break;
    default:
        {
          
        }
        break;
    }
    return _reg_read;
    }